Support config matrix for SLT tests - #24493
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #24493 +/- ##
==========================================
+ Coverage 81.43% 81.46% +0.02%
==========================================
Files 1118 1120 +2
Lines 399414 400879 +1465
Branches 399414 400879 +1465
==========================================
+ Hits 325278 326577 +1299
- Misses 55145 55224 +79
- Partials 18991 19078 +87 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
kosiew
left a comment
There was a problem hiding this comment.
Thanks for working on this. The config matrix support looks useful and the overall implementation is nicely scoped.
I found one issue that I think needs to be addressed before merging. The Substrait round-trip path currently bypasses the config matrix handling, so a matrix-bearing SLT file can silently run only once in that mode. I also left one small documentation suggestion about where the matrix tag appears in failure output.
| options.substrait_round_trip, | ||
| ) { | ||
| (_, _, true) => { | ||
| run_test_file_substrait_round_trip( |
There was a problem hiding this comment.
It looks like --substrait-round-trip still dispatches directly to run_test_file_substrait_round_trip, so this path never parses or applies configMatrix combinations.
That means an .slt file with a matrix can silently run only once in this supported mode, even though the directive suggests the file will be exercised across all combinations. Could we either route this path through the same per-combination setup, or explicitly reject configMatrix when Substrait round-trip mode is used?
It would also be good to add a regression test that verifies each matrix combination is actually executed.
| - Repeat the directive to nest keys. Values are the cartesian product. | ||
| - Whitespace-trimmed and deduped; repeated keys merge value lists. | ||
| - Unknown key or invalid value fails fast, naming the file, key, and value. | ||
| - Test failures include `[configMatrix: k=v, ...]` in the `N errors in file …` banner. |
There was a problem hiding this comment.
Small documentation nit: this says the matrix tag is included in the N errors in file ... banner, but run_test_file_once currently appends the tag to the fully formatted error after the per-record errors.
Could we either move the tag into that banner or adjust the wording here to describe where it actually appears?
|
Thanks @kosiew for the review, addressed the feedback please have another look |
kosiew
left a comment
There was a problem hiding this comment.
Thanks for working through the earlier feedback. The Substrait round-trip path now expands and applies each config matrix combination, and the README wording around the failure banner looks fixed.
I found two remaining issues that I think should be addressed before merging. The CI smoke filter points to a test file that does not exist, so the requested matrix regression coverage is still missing. There is also a compatibility regression in the new Clap handling for SLT_TIMING_DEBUG_SLOW_FILES, where previously accepted values such as 1 now cause the test binary to abort.
I left inline comments with the details and suggested fixes.
| "--", | ||
| "--substrait-round-trip", | ||
| "limit.slt", | ||
| "configmatrix_show_smoke.slt", |
There was a problem hiding this comment.
I think the regression coverage is still missing here. configmatrix_show_smoke.slt is passed as a CI filter, but there is no tracked file with that name under datafusion/sqllogictest/test_files.
Because unmatched file filters are silently ignored, this step still only runs limit.slt, so no matrix directive reaches the Substrait round-trip path. That means the earlier request for a regression test that proves every matrix combination is executed is not actually covered yet.
Could we either add the missing smoke .slt, ideally with alternatives where skipping either combination would produce an observable failure, or point this filter at an existing matrix-bearing test file?
There was a problem hiding this comment.
Thanks @kosiew this is a good catch! it was a smoke test and shouldn't be bleeding into the code
| #[clap( | ||
| long, | ||
| env = "SLT_TIMING_DEBUG_SLOW_FILES", | ||
| default_value_t = false, |
There was a problem hiding this comment.
This looks like a compatibility regression in the environment variable handling. The previous SLT_TIMING_DEBUG_SLOW_FILES parser accepted 1, true, yes, and on case-insensitively, while other values were treated as disabled. With Clap's bool parser, only true and false are accepted, and a previously valid value such as 1 now aborts the entire test binary with a usage error.
I verified this with SLT_TIMING_DEBUG_SLOW_FILES=1 cargo test -p datafusion-sqllogictest --test sqllogictests --features substrait -- --list --format terse, which exits 2 with invalid value '1'.
Could we preserve the previous parsing semantics, for example with a custom Clap value parser, or keep the existing environment-only parser and expose the CLI flag separately?
|
Thanks @kosiew for catching issues, addressed them and made the matrix be less intrusive to the runner |
kosiew
left a comment
There was a problem hiding this comment.
Thanks for continuing to work through the configMatrix support. The successful Substrait dispatch path and the legacy SLT_TIMING_DEBUG_SLOW_FILES parsing both look fixed now.
I still found two issues that I think should be addressed before merging. The first is around runtime configuration keys, and the second is that a failure in one matrix configuration prevents the remaining combinations from running.
Validation I ran:
cargo test -p datafusion-sqllogictest config_matrix --libpasses with 22 tests.- A temporary two-value matrix under
--substrait-round-trippasses and confirms the normal successful dispatch path. - A temporary matrix using
datafusion.runtime.memory_limit=100Mfails withConfig value "runtime" not found on ConfigOptions.
Thanks again for the updates here.
| /// `origin` is a display label for error messages (typically the test | ||
| /// file path). | ||
| /// | ||
| /// Note this sets config options directly rather than going through |
There was a problem hiding this comment.
I think this still leaves an important gap in what configMatrix can configure. The comment notes that these overrides are applied directly to ConfigOptions instead of going through the SessionContext SET path, but the README presents configMatrix more generally as a way to sweep configuration values.
For example, a matrix containing datafusion.runtime.memory_limit=100M currently fails with Config value "runtime" not found on ConfigOptions, even though SET datafusion.runtime.memory_limit = '100M' is supported.
Could we route matrix overrides through the same runtime-config and config-dependent UDF refresh path used by SessionContext::set_variable, or extract a shared helper for both paths? It would also be good to add coverage for a runtime setting and any config-dependent UDF behavior. If matrices are intentionally limited to ConfigOptions, then I think that narrower scope should be explicitly enforced and documented.
| .await; | ||
| pb.finish_and_clear(); | ||
|
|
||
| test_configuration.attribute_failure(result)?; |
There was a problem hiding this comment.
It looks like a failure in the first Substrait matrix configuration is still propagated with ?, so the remaining matrix combinations never run. The default runner appears to have the same behavior around line 562.
That means a file does not actually run once for every combination when an earlier combination fails, and it also makes it hard to see all configuration-specific failures in one run.
Could we keep executing the remaining configurations and aggregate the failures with enough context to identify the configuration that produced each one? I would also like to see a tracked matrix SLT or integration test where skipping a later combination is observable, so this behavior is covered for the Substrait path as well.
There was a problem hiding this comment.
Thanks @kosiew for trying this, I made a smoke test it worked, checking what is with substrait
|
Also tested with xtask/substrait, seems like working |
kosiew
left a comment
There was a problem hiding this comment.
Thanks for the follow-up work here. The previously blocking issues around runtime config handling and continuing past failed combinations look resolved. I have two remaining suggestions around keeping the default and Substrait paths from diverging and adding some end-to-end coverage. Neither is correctness blocker for the current feature.
| } | ||
|
|
||
| #[cfg(feature = "substrait")] | ||
| async fn run_test_file_substrait_round_trip( |
There was a problem hiding this comment.
Could we avoid duplicating the per-combination dispatch between run_test_file_substrait_round_trip and run_test_file? The two paths differ mainly in the engine they construct, the runner label, and the label passed to count_records, but each independently calls run_each_configuration.
I think it would be safer to collapse this into one function parameterized by a runner factory, leaving a single call site for run_each_configuration. Otherwise a future change could accidentally bypass the matrix loop in the feature-gated Substrait path while leaving the default path correct. That is essentially the structural version of the earlier Substrait bypass we fixed in this PR.
| assert!(msg.contains("boom"), "got {msg}"); | ||
| } | ||
|
|
||
| #[tokio::test] |
There was a problem hiding this comment.
It would be useful to add a small checked-in .slt containing a configMatrix directive. Right now the unit tests cover parsing, expansion, failure attribution, and continuing after failures, but no real SLT file exercises the full parse and replay path.
There is a limitation here: a passing matrix .slt cannot prove that every combination actually ran, because all combinations replay the same records and expected output. So I would not rely on this test to protect against skipped combinations. The shared dispatch refactor above is the stronger protection for that.
Still, a small matrix .slt would give useful end-to-end coverage. For Substrait, the CI step would also need to include that file because the current --substrait-round-trip limit.slt filter will not pick it up. The corresponding xtask insta snapshot would need updating as well.
Which issue does this PR close?
Rationale for this change
Config knobs like
datafusion.execution.parquet.coerce_int96andcoerce_int96_tzshould produce the same observable result across values. Today that requires a separate.sltper combination. This PRsweeps a cartesian product of config values from a single file.
What changes are included in this PR?
# configMatrix: <key>=<v1>,<v2>[,...]directive. Repeat to nest dimensions; repeated keys merge value lists.datafusion/sqllogictest/src/config_matrix.rs- parser + expansion, exportsparse_config_matrix_from_file,matrix_tag,ConfigMatrixCombination.bin/sqllogictests.rs:run_test_filedispatches once per combo viarun_test_file_once, which applies values throughconfig_mut().options_mut().set(k, v)on a freshSessionContext. Errors get asingle
[configMatrix: k=v, ...]suffix.test_files/parquet_int96_matrix.slt- 2×2 sweep overcoerce_int96andcoerce_int96_tz.datafusion/sqllogictest/README.md.Are these changes tested?
config_matrix::testscover parsing, dedup, merge, cartesian expansion, and error paths.parquet_int96_matrix.sltexercises the runner end-to-end.Are there any user-facing changes?
Additive only. Files without a directive run byte-for-byte as before. Matrix-scoped failures include
[configMatrix: ...]in the banner.